home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 4: GNU Archives / Linux Cubed Series 4 - GNU Archives.iso / gnu / glibc-1.09 / glibc-1 / glibc-1.09.1 / mach / __msg_dest.c next >
Encoding:
C/C++ Source or Header  |  1994-07-18  |  4.1 KB  |  156 lines

  1. /* 
  2.  * Mach Operating System
  3.  * Copyright (c) 1991,1990 Carnegie Mellon University
  4.  * All Rights Reserved.
  5.  * 
  6.  * Permission to use, copy, modify and distribute this software and its
  7.  * documentation is hereby granted, provided that both the copyright
  8.  * notice and this permission notice appear in all copies of the
  9.  * software, derivative works or modified versions, and any portions
  10.  * thereof, and that both notices appear in supporting documentation.
  11.  * 
  12.  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
  13.  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
  14.  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
  15.  * 
  16.  * Carnegie Mellon requests users of this software to return to
  17.  * 
  18.  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
  19.  *  School of Computer Science
  20.  *  Carnegie Mellon University
  21.  *  Pittsburgh PA 15213-3890
  22.  * 
  23.  * any improvements or extensions that they make and grant Carnegie Mellon
  24.  * the rights to redistribute these changes.
  25.  */
  26. /*
  27.  * HISTORY
  28.  * $Log: __msg_dest.c,v $
  29.  * Revision 1.2  1993/08/03  06:13:18  roland
  30.  * entered into RCS
  31.  *
  32.  * Revision 2.4  91/05/14  17:53:15  mrt
  33.  *     Correcting copyright
  34.  * 
  35.  * Revision 2.3  91/02/14  14:17:43  mrt
  36.  *     Added new Mach copyright
  37.  *     [91/02/13  12:44:15  mrt]
  38.  * 
  39.  * Revision 2.2  90/08/06  17:24:22  rpd
  40.  *     Created.
  41.  * 
  42.  */
  43.  
  44. #if 1
  45. #include <mach.h>
  46. #else
  47. /* This is what CMU did, but that fails to declare some used functions.  */
  48. #include <mach/port.h>
  49. #include <mach/message.h>
  50. #include <mach_init.h>
  51. #endif
  52.  
  53. static void mach_msg_destroy_port();
  54. static void mach_msg_destroy_memory();
  55.  
  56. /*
  57.  *    Routine:    mach_msg_destroy
  58.  *    Purpose:
  59.  *        Deallocates all port rights and out-of-line memory
  60.  *        found in a received message.
  61.  */
  62.  
  63. void
  64. __mach_msg_destroy(msg)
  65.     mach_msg_header_t *msg;
  66. {
  67.     mach_msg_bits_t mbits = msg->msgh_bits;
  68.  
  69.     /*
  70.      *    The msgh_local_port field doesn't hold a port right.
  71.      *    The receive operation consumes the destination port right.
  72.      */
  73.  
  74.     mach_msg_destroy_port(msg->msgh_remote_port, MACH_MSGH_BITS_REMOTE(mbits));
  75.  
  76.     if (mbits & MACH_MSGH_BITS_COMPLEX) {
  77.     vm_offset_t saddr;
  78.     vm_offset_t eaddr;
  79.  
  80.     saddr = (vm_offset_t) (msg + 1);
  81.     eaddr = (vm_offset_t) msg + msg->msgh_size;
  82.  
  83.     while (saddr < eaddr) {
  84.         mach_msg_type_long_t *type;
  85.         mach_msg_type_name_t name;
  86.         mach_msg_type_size_t size;
  87.         mach_msg_type_number_t number;
  88.         boolean_t is_inline;
  89.         vm_size_t length;
  90.         vm_offset_t addr;
  91.  
  92.         type = (mach_msg_type_long_t *) saddr;
  93.         is_inline = type->msgtl_header.msgt_inline;
  94.         if (type->msgtl_header.msgt_longform) {
  95.             name = type->msgtl_name;
  96.             size = type->msgtl_size;
  97.             number = type->msgtl_number;
  98.             saddr += sizeof(mach_msg_type_long_t);
  99.         } else {
  100.             name = type->msgtl_header.msgt_name;
  101.             size = type->msgtl_header.msgt_size;
  102.             number = type->msgtl_header.msgt_number;
  103.             saddr += sizeof(mach_msg_type_t);
  104.         }
  105.  
  106.         /* calculate length of data in bytes, rounding up */
  107.         length = ((((number * size) + 7) >> 3) + 3) &~ 3;
  108.  
  109.         addr = is_inline ? saddr : * (vm_offset_t *) saddr;
  110.  
  111.         if (MACH_MSG_TYPE_PORT_ANY(name)) {
  112.         mach_port_t *ports = (mach_port_t *) addr;
  113.         mach_msg_type_number_t i;
  114.  
  115.         for (i = 0; i < number; i++)
  116.             mach_msg_destroy_port(*ports++, name);
  117.         }
  118.  
  119.         if (is_inline) {
  120.         /* inline data sizes round up to int boundaries */
  121.         saddr += length;
  122.         } else {
  123.         mach_msg_destroy_memory(addr, length);
  124.         saddr += sizeof(vm_offset_t);
  125.         }
  126.     }
  127.     }
  128. }
  129.  
  130. static void
  131. mach_msg_destroy_port(port, type)
  132.     mach_port_t port;
  133.     mach_msg_type_name_t type;
  134. {
  135.     if (MACH_PORT_VALID(port)) switch (type) {
  136.       case MACH_MSG_TYPE_PORT_SEND:
  137.       case MACH_MSG_TYPE_PORT_SEND_ONCE:
  138.     (void) __mach_port_deallocate(__mach_task_self(), port);
  139.     break;
  140.  
  141.       case MACH_MSG_TYPE_PORT_RECEIVE:
  142.     (void) __mach_port_mod_refs(__mach_task_self(), port,
  143.                     MACH_PORT_RIGHT_RECEIVE, -1);
  144.     break;
  145.     }
  146. }
  147.  
  148. static void
  149. mach_msg_destroy_memory(addr, size)
  150.     vm_offset_t addr;
  151.     vm_size_t size;
  152. {
  153.     if (size > 0)
  154.     (void) __vm_deallocate(__mach_task_self(), addr, size);
  155. }
  156.